package com.yiwyn.demo.scanner;

import com.yiwyn.demo.anno.Task;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Component
public class TaskMethodScanner implements ApplicationRunner {

    @Autowired
    private ApplicationContext applicationContext;

    // 用于存储类名和方法名的数组
    private final Map<Integer, AnnotationScanner.TaskNode> methodList = new HashMap<>();

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(org.springframework.stereotype.Service.class);

        for (Object bean : beans.values()) {
            Class<?> beanClass = bean.getClass();
            for (Method method : beanClass.getDeclaredMethods()) {
                // 判断方法上是否有 @MyCustomAnnotation 注解
                if (method.isAnnotationPresent(Task.class)) {
                    // 将类名和方法名存入数组
                    Task annotation = method.getAnnotation(Task.class);
                    AnnotationScanner.TaskNode taskNode = new AnnotationScanner.TaskNode();
                    taskNode.setMethod(method);
                    taskNode.setBean(bean);
                    taskNode.setHasParam(annotation.hasParam());
                    int key = annotation.apiCode();
                    if (methodList.containsKey(key)) {
                        throw new RuntimeException("@Task 重复定义apiCoce");
                    }
                    methodList.put(key, taskNode);
                }
            }
        }

    }

    // 获取方法名数组的方法
    public Map<Integer, AnnotationScanner.TaskNode> getMethodNames() {
        return methodList;
    }

    @Data
    public static class TaskNode {
        private Boolean hasParam;
        private Object bean;
        private Method method;
    }
}